跳到主要内容

typer 综览

https://typer.tiangolo.com/

clickArgparse 的升级版,而 typer 则是 click 的升级版,其中最大的优势就是可以通过参数的类型识别来快速建立 CLI

初识

最简单的单命令版本:

import typer


def main(name: str, lastname: str, formal: bool = False):
if formal:
print(f"Good day Ms. {name} {lastname}.")
else:
print(f"Hello {name} {lastname}")


if __name__ == "__main__":
typer.run(main)

其中,name 和 lastname 被称为 CLI 参数(CLI Argument),formal 被称为 CLI 选项(CLI Option)

两者的区别:

  • CLI options start with -- and don't depend on the order
  • CLI arguments depend on the sequence order

在 Typer 的构建中:

  • A CLI argument is required
  • A CLI option is optional

在 Typer 中,CLI argument + CLI option = CLI parameter

typer 命令

typer 提供了一个 typer 命令,以期实现自动补全

$ python main.py

Hello World

# 可以被替换为
$ typer main.py run

Hello World

输出

可以使用简单的 print 来向屏幕打印信息

import typer


def main():
print("Hello World")


if __name__ == "__main__":
typer.run(main)

使用 Rich

可以使用 rich 库来实现更加丰富的打印效果

rich 库随着 typer 一起安装,可以直接使用

import typer
from rich import print

data = {
"name": "Rick",
"age": 42,
"items": [{"name": "Portal Gun"}, {"name": "Plumbus"}],
"active": True,
"affiliation": None,
}


def main():
print("Here's the data")
print(data)


if __name__ == "__main__":
typer.run(main)

中止命令

使用 Exit 退出

you can raise a typer.Exit() exception:

import typer

existing_usernames = ["rick", "morty"]


def maybe_create_user(username: str):
if username in existing_usernames:
print("The user already exists")
raise typer.Exit()
else:
print(f"User created: {username}")


def send_new_user_notification(username: str):
# Somehow send a notification here for the new user, maybe an email
print(f"Notification sent for new user: {username}")


def main(username: str):
maybe_create_user(username=username)
send_new_user_notification(username=username)


if __name__ == "__main__":
typer.run(main)

这样的话,当输入一个不被识别的人名时,程序会中止,并不会运行 send_new_user_notification() 函数

typer.Exit() 并不意味着程序的异常,而是一个正常的退出,typer 会捕获这个异常,并且不会显示任何错误信息

退出并抛出错误

typer.Exit() 提供 code 参数. By default, code is 0, 代表没有错误

code 设置为非 0 值时,会抛出一个错误

import typer


def main(username: str):
if username == "root":
print("The root user is reserved")
raise typer.Exit(code=1)
print(f"New user created: {username}")


if __name__ == "__main__":
typer.run(main)
image-20240710140732041

The error code might be used by other programs (for example a Bash script) that execute your CLI program.

Abort

使用 typer.Abort() 来抛出明显的 Aborted 错误

import typer


def main(username: str):
if username == "root":
print("The root user is reserved")
raise typer.Abort()
print(f"New user created: {username}")


if __name__ == "__main__":
typer.run(main)
image-20240710141122130